/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Logica;

import Logica.DTO.DTOListarPartida;
import Logica.DTO.DTOPartida;
import Logica.Excepciones.InicializarPartidaException;
import Logica.Excepciones.UnirsePartidaException;
import Logica.Excepciones.FinalizarPartidaException;
import Logica.Excepciones.NoHayPartidasNuevasException;
import Logica.Excepciones.NoHayPartidasIniciadasException;
import Logica.Excepciones.NoHayPartidasEnJuegoException;
import Logica.Excepciones.NombreDuplicadoException;
import Logica.Excepciones.NombreIncorrectoException;
import Logica.Excepciones.NombrePartidaDuplicadoException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;

/**
 *
 * @author Cami
 */
public class Fachada extends UnicastRemoteObject implements IFachada {
    
    	private Partidas partidas;     
        
        public Fachada() throws IOException, ClassNotFoundException {
            partidas = new Partidas();
           //this.cargarCambios();
	}
                
       	public LinkedList<DTOListarPartida> listarPartidasNuevas() throws NoHayPartidasNuevasException {
		if (!partidas.isEmptyPartidasNuevas())
		{
			LinkedList<DTOListarPartida> dtoPartidasNvas = new LinkedList<DTOListarPartida>();
			Iterator<Partida> iter = this.partidas.getPartidasNuevas().values().iterator();
			while(iter.hasNext()) {
				Partida pAux = iter.next();
				DTOListarPartida dtoPartida = new DTOListarPartida(pAux.getNombrePartida(), pAux.getEstado(), pAux.getGanador()); 
				dtoPartidasNvas.add(dtoPartida);
			}
			return dtoPartidasNvas;
		}else
		{
			throw new NoHayPartidasNuevasException();
		}
	}      
        public LinkedList<DTOListarPartida> listarPartidasInic() throws NoHayPartidasIniciadasException {
		if (!partidas.isEmptyPartidasNuevas())
		{
			LinkedList<DTOListarPartida> dtoPartidasNvas = new LinkedList<DTOListarPartida>();
			Iterator<Partida> iter = this.partidas.getPartidasInic().values().iterator();
			while(iter.hasNext()) {
				Partida pAux = iter.next();
				DTOListarPartida dtoPartida = new DTOListarPartida(pAux.getNombrePartida(), pAux.getEstado(), pAux.getGanador()); 
				dtoPartidasNvas.add(dtoPartida);
			}
			return dtoPartidasNvas;
		}else
		{
			throw new NoHayPartidasIniciadasException();
		}
	} 
        public LinkedList<DTOListarPartida> listarPartidasEnJueg() throws NoHayPartidasEnJuegoException {
		if (!partidas.isEmptyPartidasNuevas())
		{
			LinkedList<DTOListarPartida> dtoPartidasNvas = new LinkedList<DTOListarPartida>();
			Iterator<Partida> iter = this.partidas.getPartidasEnJueg().values().iterator();
			while(iter.hasNext()) {
				Partida pAux = iter.next();
				DTOListarPartida dtoPartida = new DTOListarPartida(pAux.getNombrePartida(), pAux.getEstado(), pAux.getGanador()); 
				dtoPartidasNvas.add(dtoPartida);
			}
			return dtoPartidasNvas;
		}else
		{
			throw new NoHayPartidasEnJuegoException();
		}
	} 
        
        
        public void crearPartida(String nombrePartida, String nombreCorsario, String nombrePirata )
            throws NombrePartidaDuplicadoException, NombreDuplicadoException {
        
                if (!(this.partidas.memberPartidas(nombrePartida))){
                    //Validar mismo nombre corsario y pirata?
                    if (!nombreCorsario.equals(nombrePirata)){
                        Partida p = new Partida(nombrePartida,nombreCorsario,nombrePirata);
                        partidas.insertPartidasInic(p);
                    }else{
                        throw new NombreDuplicadoException();
                    }
                }else
                {
                    throw new NombrePartidaDuplicadoException();
                }       
        }
                  
        public void iniciarNvaPartida(DTOPartida dtoPartida)
            throws NoHayPartidasNuevasException, InicializarPartidaException {
                                                          
                if (!this.partidas.isEmptyPartidasNuevas()){
                    String nombrePartida=dtoPartida.getNombrePart();
                    if (this.partidas.memberPartidasNuevas(nombrePartida)){
                        Partida p = this.partidas.findPartidasNuevas(nombrePartida);
                       
                        //VALIDAR USUARIO??
                        	
                        //Obtengo del DTO los datos del Puerto Origen
                        int cXPOrigen = dtoPartida.getCoorXPOrigen();
                        int cYPOrigen = dtoPartida.getCoordYPOrigen();
                        Coordenadas cPOrigen = new Coordenadas (cXPOrigen, cYPOrigen);
                        
                        //Creo el Puerto de Origen de los datos obtenidos
                   
                        Puerto pOrigen= new Puerto(1,1, cPOrigen);
                        
                        //Obtengo ddel DTO los datos del Puerto Destino
                        int cXPDestino = dtoPartida.getCoordXPDest();
                        int cYPDestino = dtoPartida.getCoordYPDest();
                        Coordenadas cPDestino = new Coordenadas (cXPDestino, cYPDestino);
                        int aPDestino= dtoPartida.getLargoPDest();
                        int lPDestino=dtoPartida.getAnchoPDest();
                                
                        //Creo el Puerto Destino de los datos Obtenidos
                        Puerto pDestino= new Puerto(lPDestino,aPDestino, cPDestino);
                        
                        //Asigno los Puertos de Origen y Destino a la partida.
                        p.asignarOrigen(pOrigen);
                        p.asignarDestino(pDestino);

                        //Obtengo del DTO los datos del baco corsario
                        int aBarco = dtoPartida.getAnchoBarco();
                        int lBarco = dtoPartida.getLargoBarco();
                        int vBarco=dtoPartida.getVelBarco();
                        int alcBalaBarco=dtoPartida.getAlcanceBalaBarco();
                        
                        //int dBarco=dtoPartida.getDistDisparoBarco();
                        //int rBarco=dtoPartida.getRangoBarco();
                        
                        //Creo el Barco Corsario con los datos Obtenidos
                        Barco corsario = new Barco (lBarco,aBarco,cPOrigen,vBarco);
                        
                        int lCanon= (lBarco)/4;
                        int aCanon=(aBarco)/2;
                        
                        Coordenadas CoordC1= new Coordenadas (cXPOrigen, cYPOrigen);
                        Coordenadas CoordC2= new Coordenadas (cXPOrigen+lCanon, cYPOrigen);
                        Coordenadas CoordC3= new Coordenadas (cXPOrigen+lCanon+lCanon, cYPOrigen);
                        Coordenadas CoordC4= new Coordenadas (cXPOrigen+lCanon+lCanon+lCanon, cYPOrigen);
                        
                        Coordenadas CoordC5= new Coordenadas (cXPOrigen, cYPOrigen+aCanon);
                        Coordenadas CoordC6= new Coordenadas (cXPOrigen+lCanon,cYPDestino+aCanon);
                        Coordenadas CoordC7= new Coordenadas (cXPOrigen+lCanon+lCanon,cYPOrigen+aCanon);
                        Coordenadas CoordC8= new Coordenadas (cXPOrigen+lCanon+lCanon+lCanon,cYPOrigen+aCanon);
                        
                        Canon c1 = new Canon (lCanon,aCanon,CoordC1,alcBalaBarco);
                        Canon c2 = new Canon (lCanon,aCanon,CoordC2,alcBalaBarco);
                        Canon c3 = new Canon (lCanon,aCanon,CoordC3,alcBalaBarco);
                        Canon c4 = new Canon (lCanon,aCanon,CoordC4,alcBalaBarco);
                        Canon c5 = new Canon (lCanon,aCanon,CoordC5,alcBalaBarco);
                        Canon c6 = new Canon (lCanon,aCanon,CoordC6,alcBalaBarco);
                        Canon c7 = new Canon (lCanon,aCanon,CoordC7,alcBalaBarco);
                        Canon c8 = new Canon (lCanon,aCanon,CoordC8,alcBalaBarco);
                        
                       corsario.insFrontCanones(c8);
                       corsario.insFrontCanones(c7);
                       corsario.insFrontCanones(c6);
                       corsario.insFrontCanones(c5);
                       corsario.insFrontCanones(c4);
                       corsario.insFrontCanones(c3);
                       corsario.insFrontCanones(c2);
                       corsario.insFrontCanones(c1);
                       
                        //Asigno el Barco a la partida
                        p.asignarCorsario(corsario);
                           
                        //Cambio estado y muevo a la coleccion correspondiente
                        p.iniciarPartida();
                        this.partidas.deletePartidasNuevas(nombrePartida);
                        this.partidas.insertPartidasInic(p);
                       
                            }else{
                                throw new InicializarPartidaException();
                            }
                        }else{
                            throw new NoHayPartidasNuevasException();
			}
        }
        
        public void unirsePartida(DTOPartida dtoPartida)
            throws NoHayPartidasIniciadasException, UnirsePartidaException{
            
		if (this.partidas.isEmptyPartidasInic()){
                    String nombrePartida=dtoPartida.getNombrePart();
                    if (this.partidas.memberPartidasInic(nombrePartida)){
                        Partida p = this.partidas.findPartidasInic(nombrePartida);
                        //validar usuario???
                       
                        //Obtengo ddel DTO los datos de las Lanchas Piratas
                        int velLancha=dtoPartida.getVelLancha();
                        int alcBalaLancha=dtoPartida.getAlcanceBalaLancha();
                        int aLancha=dtoPartida.getAnchoLancha();
                        int lLancha=dtoPartida.getLargoLancha();
                        
                        //Las tres lanchas comienzan de la misma coordenada (1,1)
                        int coordYL = 1;
                        int coordXL = 1;
                        
                        Coordenadas coordL = new Coordenadas (coordXL,coordYL);
                        
                        Lancha pirata1=new Lancha (lLancha,aLancha,coordL,velLancha, alcBalaLancha);
                        Lancha pirata2=new Lancha (lLancha,aLancha,coordL,velLancha, alcBalaLancha);
                        Lancha pirata3=new Lancha (lLancha,aLancha,coordL,velLancha, alcBalaLancha);
                        //Asigno las 3 lanchas piratas a la partida
                        
                        p.insFrontPiratas(pirata3);
                        p.insFrontPiratas(pirata2);
                        p.insFrontPiratas(pirata1);
                        
                        p.unirsePartida();
                        this.partidas.deletePartidasInic(nombrePartida);
                        this.partidas.insertPartidasEnJueg(p);       
                     }else{
                        throw new UnirsePartidaException();
                    }
                }else{
                    throw new NoHayPartidasIniciadasException();
		}
        }
        
        
        public void moverBarcoDelante (String nombrePartida){
            
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();          
            int nuevaXBarco = pAux.getCorsario().getCoord().getCoordX();
            int nuevaYBarco = pAux.getCorsario().getCoord().getCoordY()+ velBarco;    
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXBarco,nuevaYBarco);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        } 
        public void moverBarcoAtras (String nombrePartida){
           
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();
            int nuevaXBarco = pAux.getCorsario().getCoord().getCoordX();
            int nuevaYBarco = pAux.getCorsario().getCoord().getCoordY()- velBarco;
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXBarco,nuevaYBarco);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        }
        public void moverBarcoDerecha (String nombrePartida){
            
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();
            int nuevaXBarco = pAux.getCorsario().getCoord().getCoordX()+ velBarco;
            int nuevaYBarco = pAux.getCorsario().getCoord().getCoordY();
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXBarco,nuevaYBarco);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        }
        public void moverBarcoIzq (String nombrePartida){
            
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();
            int nuevaXBarco = pAux.getCorsario().getCoord().getCoordX()- velBarco;
            int nuevaYBarco = pAux.getCorsario().getCoord().getCoordY();
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXBarco,nuevaYBarco);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        }
        
        public void moverLanchaDelante (String nombrePartida, int nroLancha){

            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velLancha = pAux.nesimaLancha(nroLancha).getVelLancha();    
            int nuevoXLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordX();
            int nuevaYLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordY()+ velLancha;
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevoXLancha,nuevaYLancha);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        } 
        public void moverLanchaAtras (String nombrePartida, int nroLancha){
            
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velLancha = pAux.nesimaLancha(nroLancha).getVelLancha(); 
            int nuevaXLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordX();
            int nuevaYLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordY()- velLancha;
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXLancha,nuevaYLancha);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);
        }
        public void moverLanchaDerecha (String nombrePartida, int nroLancha){

            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();
            int nuevaXLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordX()+ velBarco;
            int nuevaYLancha = pAux.nesimaLancha(nroLancha).getCoord().getCoordY();
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXLancha,nuevaYLancha);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);

        }
        public void moverLanchaIzq (String nombrePartida, int nroLancha){
           
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            int velBarco = pAux.getCorsario().getVelocidadBarco();
            int nuevaXLancha = pAux.getCorsario().getCoord().getCoordX()- velBarco;
            int nuevaYLancha = pAux.getCorsario().getCoord().getCoordY();
            Coordenadas nuevaCoordBarco= new Coordenadas (nuevaXLancha,nuevaYLancha);
            pAux.getCorsario().setCoord(nuevaCoordBarco);
            this.partidas.modifyPartidasEnJueg(pAux);

        }
        
        public void chocaLanchaBarco (String nombrePartida){
            
            Partida pAux= this.partidas.findPartidasEnJueg(nombrePartida);
            Barco bAux= pAux.getCorsario();
            Lancha lAux1 = pAux.nesimaLancha(1);
            Lancha lAux2 = pAux.nesimaLancha(2);   
            Lancha lAux3 = pAux.nesimaLancha(3);
            
            
            
        }
       
        
        
        public void finalizarPartida (DTOPartida dtoPartida)
            throws NoHayPartidasEnJuegoException, FinalizarPartidaException {
        
		if (this.partidas.isEmptyPartidasEnJueg()){
                    String nombrePartida=dtoPartida.getNombrePart();
                    if (this.partidas.memberPartidasEnJueg(nombrePartida)){
                        Partida p = this.partidas.findPartidasInic(nombrePartida);
                        p.finalizarPartida(dtoPartida.getNombreGanador());
                        this.partidas.deletePartidasInic(nombrePartida);
                        this.partidas.insertPartidasEnJueg(p);
                     }else{
                        throw new FinalizarPartidaException();
                    }
                }else{
                    throw new NoHayPartidasEnJuegoException();
		}
            
        }
      
        
        
        //MODIFICAR DESPUES DE DEFINIR COMO IDENTIFICO SESION??
        public boolean logInCorsario(Partida p, String nombreC) 
            throws  NombreIncorrectoException {
            
		boolean logIn = false;
                if (p.getNombreCorsario().equals(nombreC)){
                    logIn=true;
                }else{
                    throw new NombreIncorrectoException();
                }
                return logIn;
	}
        
        public boolean logInPirata(Partida p, String  nombreP) 
            throws  NombreIncorrectoException {
            
		boolean logIn = false;
                if (p.getNombrePirata().equals(nombreP)){
                    logIn=true;
                }else{
                    throw new NombreIncorrectoException();
                }
                return logIn;
	}
        

    }
 
                
        
